﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace Wzh_CheckAB
{
    public static class UnityMathfTool
    {
        #region 获得坐标点
        /// <summary>是奇数</summary>
        public static bool IsOdd(int value)
        {
            return value % 2 == 1;
        }
        /// <summary>获得圆周上一个点 XY平面</summary>
        public static Vector3 GetCircumferencePos(Vector3 centPos, float radius, float ang)
        {
            Vector3 pos = Vector3.zero;
            pos.x = centPos.x + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
            pos.y = centPos.y + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
            pos.z = centPos.z;
            return pos;
        }
        /// <summary>获得圆周上一个点 XY平面</summary>
        public static Vector3 GetCircumferencePos(Vector3 centPos, float radius)
        {
            return GetCircumferencePos(centPos, radius, RandomValue(0, 360));
        }
        /// <summary>获得圆周上一个点 XZ平面</summary>
        public static Vector3 GetCircumferencePosXZ(Vector3 centPos, float radius, float ang)
        {
            Vector3 pos = Vector3.zero;
            pos.x = centPos.x + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
            pos.z = centPos.z + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
            pos.y = centPos.y;
            return pos;
        }
        /// <summary>获得圆周上一个点 XZ平面</summary>
        public static Vector3 GetCircumferencePosXZ(Vector3 centPos, float radius)
        {
            return GetCircumferencePosXZ(centPos, radius, RandomValue(0, 360));
        }
        /// <summary>获得中心点 按百分比</summary>
        public static Vector3 GetBetweenPointByPer(Vector3 start, Vector3 end, float percent = 0.5f)
        {
            Vector3 normal = (end - start).normalized;
            float distance = Vector3.Distance(start, end);
            return normal * (distance * percent) + start;
        }

        /// <summary>获得中心点 按距离</summary>
        public static Vector3 GetBetweenPointByDis(Vector3 start, Vector3 end, float distance)
        {
            Vector3 normal = (end - start).normalized;
            return normal * distance + start;
        }
        /// <summary>Cube绕着某一点旋转任意角度</summary>
        public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
        {
            Vector3 point = Quaternion.AngleAxis(angle, axis) * (position - center);
            Vector3 resultVec3 = center + point;
            return resultVec3;
        }
        /// <summary>Vector3转Vector3Int 前移小数点几位 </summary>
        public static Vector3Int GetVector3IntRoundPoint(Vector3 targetV3, int posSite)
        {
            return new Vector3Int(GetFloatToIntRoundPoint(targetV3.x, posSite)
                , GetFloatToIntRoundPoint(targetV3.y, posSite)
                , GetFloatToIntRoundPoint(targetV3.z, posSite));
        }
        /// <summary>前移float 小数点几位 并返回int</summary>
        public static int GetFloatToIntRoundPoint(float value, int posSite)
        {
            int preNum = (int)Mathf.Pow(10, posSite);
            return (int)(value * preNum);
        }
        /// <summary>后移int 小数点几位 并返回float</summary>
        public static float GetIntToFloatRoundPoint(int value, int posSite)
        {
            float preNum = Mathf.Pow(10, posSite) ;
            return value / preNum;
        }
        /// <summary>Vector3Int转Vector3 后移小数点几位 </summary>
        public static Vector3 GetVector3ByVector3Int(Vector3Int pos, int posSite)
        {
            float preNum = Mathf.Pow(10, posSite) ;
            return new Vector3(pos.x / preNum, pos.y / preNum, pos.z / preNum);
        }
        public static string Vector3IntToString(Vector3Int pos, char cha)
        {
            return $"{pos.x}{cha}{pos.y}{cha}{pos.z}";
        }
        public static Vector3Int StringToVector3Int(string pos, char cha)
        {
            if (string.IsNullOrEmpty(pos)) return Vector3Int.zero;

            int[] posIntArray = StringToIntArray(pos, cha, 0);
            Vector3Int resV3 = Vector3Int.zero;
            resV3.x = GetValueFromArray(posIntArray, 0, 0);
            resV3.y = GetValueFromArray(posIntArray, 1, 0);
            resV3.z = GetValueFromArray(posIntArray, 2, 0);
            return resV3;
        }
        /// <summary>设置父物体 并且初始话位置和大小旋转</summary>
        public static void SetParentToNorm(this Transform childTrans, Transform parentTrans)
        {
            if (childTrans == null || parentTrans == null) return;
            childTrans.SetParent(parentTrans);
            childTrans.TransformToNorm();
        }
        /// <summary>设置父物体 并且初始话位置和大小旋转</summary>
        public static void SetParentTranlocalInfo(this Transform childTrans, Transform parentTrans, Vector3 pos, Vector3 angles, Vector3 scale)
        {
            if (childTrans == null || parentTrans == null) return;
            childTrans.SetParent(parentTrans);
            childTrans.localPosition = pos;
            childTrans.localScale = scale;
            childTrans.localEulerAngles = angles;
        }
        /// <summary>设置父物体 并且初始话位置和大小旋转</summary>
        public static void SetParentTranlocalInfo(this Transform childTrans, Transform parentTrans, Vector3 pos)
        {
            if (childTrans == null || parentTrans == null) return;
            childTrans.SetParent(parentTrans);
            childTrans.localPosition = pos;
        }
        public static void SetParentTranlocalInfo(this Transform childTrans, Transform parentTrans, Transform othrTrans)
        {
            if (childTrans == null || parentTrans == null) return;
            childTrans.SetParent(parentTrans);
            if (othrTrans == null) return;
            childTrans.localPosition = othrTrans.localPosition;
            childTrans.localScale = othrTrans.localScale;
            childTrans.localEulerAngles = othrTrans.localEulerAngles;
        }
        /// <summary>初始话位置和大小旋转</summary>
        public static void TransformToNorm(this Transform childTrans)
        {
            if (childTrans == null) return;
            childTrans.localPosition = Vector3.zero;
            childTrans.localScale = Vector3.one;
            childTrans.localEulerAngles = Vector3.zero;
        }
        /// <summary>标准话物体和所有子物体</summary>
        public static void TransformNormalizing(this Transform childTrans)
        {
            if (childTrans == null) return;
            if (childTrans.name == "Cube") return;
            for (int i = 0; i < childTrans.childCount; i++)
                TransformNormalizing(childTrans.GetChild(i));
            childTrans.localPosition = Vector3.zero;
            childTrans.localScale = Vector3.one;
            childTrans.localEulerAngles = Vector3.zero;
            childTrans.gameObject.SetActive(true);
        }
        public static void TransformCopyValue(this Transform childTrans, Transform otherTrans)
        {
            if (childTrans == null || otherTrans == null) return;
            childTrans.position = otherTrans.position;
            childTrans.localScale = otherTrans.localScale;
            childTrans.eulerAngles = otherTrans.eulerAngles;
        }
        /// <summary>获得Transform单轴转了几步 axis=0-x,1-y,n-z  isSinge单圈步数 isActive判定显隐</summary>
        public static int GetTransformSingleAxisRotateNum(Transform transform, Vector3 rotationStep, int axis, bool isSinge, bool isActive)
        {
            if (transform == null) return 0;
            if (isActive && transform.gameObject.activeSelf == false) return 0;
            Vector3 localPos = transform.localEulerAngles;
            float nomAxis = rotationStep.z;
            float targetAxis = localPos.z;
            if (axis == 0) { nomAxis = rotationStep.x; targetAxis = localPos.x; }
            else if (axis == 1) { nomAxis = rotationStep.y; targetAxis = localPos.y; }
            if (nomAxis == 0 || targetAxis == 0) return 0;

            int sumStep = Mathf.RoundToInt(targetAxis / nomAxis);//总步数

            if (sumStep > 0 && isSinge == false) return sumStep;

            int nomNum = Mathf.RoundToInt(360 / Mathf.Abs(nomAxis));//一圈标准步数
            int multipleNum = Mathf.Abs(sumStep) / nomNum; //倍数
            int remainderNum = sumStep % nomNum;//余数
            if (remainderNum < 0) remainderNum = nomNum + remainderNum;//矫正 小于0的值

            return isSinge ? remainderNum : (multipleNum * nomNum + remainderNum);
        }
        /// <summary>设置Transform单轴转了几步 axis=0-x,1-y,n-z  isAdd是增量旋转还绝对旋转</summary>
        public static void SetTransformSingleAxisRotateNum(Transform transform, int stepNum, Vector3 rotationStep, int axis, bool isAdd)
        {
            if (transform == null) return;
            Vector3 targetV3 = Vector3.zero;
            if (axis == 0) { targetV3.x = rotationStep.x * stepNum; }
            else if (axis == 1) { targetV3.y = rotationStep.y * stepNum; }
            else { targetV3.z = rotationStep.z * stepNum; }

            transform.localEulerAngles = isAdd ? transform.localEulerAngles + targetV3 : targetV3;
        }


        /// <summary> 通过世界坐标设置UI的位置 </summary>
        public static void Do_SetUIPositionByWorldPos(this RectTransform rectTransform, Camera targetCamera, Camera originalCamera, Vector3 originalPos)
        {
            if (rectTransform == null || targetCamera == null) return;

            rectTransform.position = WorldPosToUIPos(targetCamera, originalCamera, originalPos);
            rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y, 0);
        }

        /// <summary> 原相机坐标 转目标相机坐标 </summary>
        public static Vector3 WorldPosToUIPos(Camera targetCamera, Camera originalCamera, Vector3 originalPos)
        {
            if (targetCamera == null) return originalPos;
            Vector3 screenPos = originalCamera.WorldToScreenPoint(originalPos);
            // Z小于0，代表在相机后面，此时X、Y反向；
            if (screenPos.z < 0)
            {
                screenPos.x *= -1;
                screenPos.y *= -1;
            }
            return targetCamera.ScreenToWorldPoint(screenPos);
        }

        /// <summary>获得缩放倍数 适配显示区域  </summary>
        public static float GetAdaptiveScaleSlotRoot(float wide, float high, float size)
        {
            return 1 / Mathf.Max(wide / size, high / size);
        }
     
        public static bool IsTouchedUI()
        {
            if (Application.isMobilePlatform)
            {
                if (Input.touchCount > 0
                    && UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
                {
                    return true;
                }
            }
            else if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
            {
                return true;
            }
            return false;
        }
        #endregion

        #region 贝塞尔 曲线点
        /// <summary> 一阶 贝塞尔 曲线点  t=0~1，0起点 1终点</summary>
        public static Vector3 GetBezierPoint(Vector3 start, Vector3 end, float t)
        {
            t = Mathf.Clamp(t, 0, 1);
            return (1 - t) * start + t * end;
        }

        /// <summary> 三阶 贝塞尔 曲线点  t=0~1，0起点 1终点 </summary>
        public static Vector3 GetBezierPoint(Vector3 start, Vector3 center1, Vector3 center2, Vector3 end, float t)
        {
            t = Mathf.Clamp(t, 0, 1);
            float t0 = 1 - t;
            return t0 * t0 * t0 * start + 3 * t0 * t0 * t * center1 + 3 * t0 * t * t * center2 + t * t * t * end;
        }
        /// <summary> 二阶 贝塞尔 曲线点  t=0~1，0起点 1终点 </summary>
        public static Vector3 GetBezierPoint(Vector3 start, Vector3 center, Vector3 end, float t)
        {
            t = Mathf.Clamp(t, 0, 1);
            float t0 = 1 - t;
            return t0 * t0 * start + 2 * t0 * t * center + t * t * end;
        }
        /// <summary> 二阶 贝塞尔 曲线点 二阶 perHigh 中点0~1 perCenter 中点 在连线位置百分比 0~1范围  </summary>
        public static Vector3 GetBezierPoint(Vector3 start, Vector3 end, float t, float perHigh, float perCenter)
        {
            Vector3 center = GetBezierCenterPoint(start, end, perHigh, perCenter);
            return GetBezierPoint(start, center, end, t);
        }

        /// <summary> 二阶 贝塞尔 曲线点数组  posNum 取个点数 </summary>
        public static Vector3[] GetBezierPointArray(Vector3 start, Vector3 center, Vector3 end, int posNum = 3)
        {
            Vector3[] _path = new Vector3[posNum];//posNum，表示要取得路径点数量，值越大，取得的路径点越多，曲线最后越平滑
            for (int i = 0; i < posNum; i++)
            {
                var time = (i + 1) / (float)posNum;//归化到0~1范围
                _path[i] = GetBezierPoint(start, center, end, time);//使用贝塞尔曲线的公式取得t时的路径点
            }
            return _path;
        }
        /// <summary> 二阶 贝塞尔 曲线点数组  perHigh 中点高 0~1 perCenter 中点 在连线位置百分比 0~1范围  </summary>
        public static Vector3[] GetBezierPointArray(Vector3 start, Vector3 end, int posNum = 3, float perHigh = 0.5f, float perCenter = 0.5f)
        {
            Vector3 center = GetBezierCenterPoint(start, end, perHigh, perCenter);
            return GetBezierPointArray(start, center, end, posNum);
        }
        /// <summary> 二阶 贝塞尔 曲线点数组  posNum 取个点数 </summary>
        public static List<Vector3> GetBezierPointList(Vector3 start, Vector3 center, Vector3 end, int posNum = 3, List<Vector3> posList = null)
        {
            if (posList == null) posList = new List<Vector3>();
            posList.Clear();
            float sumNum = (float)posNum;
            //posNum，表示要取得路径点数量，值越大，取得的路径点越多，曲线最后越平滑
            for (int i = 0; i < posNum; i++)
            {
                var time = (i + 1) / sumNum;//归化到0~1范围
                posList.Add(GetBezierPoint(start, center, end, time));//使用贝塞尔曲线的公式取得t时的路径点
            }
            return posList;
        }
        /// <summary>  贝塞尔 中点  perHigh 中点高 0~1 perCenter 中点 在连线位置百分比 0~1范围   </summary>
        public static Vector3 GetBezierCenterPoint(Vector3 start, Vector3 end, float perHigh = 0.5f, float perCenter = 0.5f)
        {
            ////获得垂直 start end 面的垂线
            Vector3 tpTLine = Vector3.Cross(start, end);

            Vector3 dir = end - start;

            float dirDis = dir.magnitude;

            //获得垂直 dir的垂线
            Vector3 Tline = Vector3.Cross(tpTLine, dir).normalized;
            if (tpTLine.z >= 0) Tline *= -1;

            return start + Tline * dirDis * perHigh + dir.normalized * dirDis * perCenter;
        }
        /// <summary>  贝塞尔 中点  perHigh 中点高 0~1 perCenter 中点 在连线位置百分比 0~1范围   </summary>
        public static Vector3 GetBezierCenterPosXY(Vector3 start, Vector3 end, float perHigh = 0.5f, float perCenter = 0.5f)
        {
            Vector3 Tmo = Vector3.Cross(start, end);
            Vector3 dir = end - start;

            float dirDis = dir.magnitude;

            //获得垂直 dir的垂线
            Vector3 Tline = Vector3.Cross(Tmo, dir).normalized;

            return start + Tline * dirDis * perHigh + dir.normalized * dirDis * perCenter;
        }
        /// <summary> 到达目标时间戳    </summary>
        public static float GetSpeedTime(Vector3 start, Vector3 end, float speed)
        {
            return Vector2.Distance(start, end) / speed;
        }
        /// <summary> 获得 位的数值    </summary>
        public static int GetIntSiteNum(int value, int posSite)
        {
            return (value % (int)Mathf.Pow(10, posSite + 1)) / (int)Mathf.Pow(10, posSite);
        }
        #endregion

        #region 操作集合
        /// <summary> 数组随机排序 </summary>
        public static void SortRandomArray<T>(T[] TArray)
        {
            int randIndex = 0;
            T tpItem;
            for (int i = 0; i < TArray.Length; i++)
            {
                randIndex = Random.Range(0, TArray.Length);
                if (i == randIndex) continue;
                tpItem = TArray[i];
                TArray[i] = TArray[randIndex];
                TArray[randIndex] = tpItem;
            }
        }
        /// <summary> list随机排序 </summary>
        public static void SortRandomtList<T>(List<T> ListT)
        {
            int randIndex = 0;
            T tpItem;
            for (int i = 0; i < ListT.Count; i++)
            {
                randIndex = Random.Range(0, ListT.Count);
                if (i == randIndex) continue;
                tpItem = ListT[i];
                ListT[i] = ListT[randIndex];
                ListT[randIndex] = tpItem;
            }
        }

        /// <summary> 数组反转 </summary>
        public static void ReverseArray<T>(T[] TArray)
        {
            if (TArray == null || TArray.Length <= 1) return;
            T tpItem;
            int randIndex = 0;
            int Length = TArray.Length - 1;
            for (int i = 0; i <= Length; i++)
            {
                randIndex = Length - i;
                if (i >= randIndex) break;
                tpItem = TArray[i];
                TArray[i] = TArray[randIndex];
                TArray[randIndex] = tpItem;
            }
        }

        public static void SetArrayValueDefault<T>(T[] array, T value)
        {
            if (array == null || array.Length == 0) return;
            for (int i = 0; i < array.Length; i++)
                array[i] = value;
        }
        public static T[] SetArrayValue<T>(T[] array, T[] fromArray)
        {
            if (array == null || array.Length == 0) return null;
            if (fromArray == null || fromArray.Length == 0) return null;
            for (int i = 0; i < array.Length; i++)
                array[i] = fromArray[i];

            return array;
        }
        /// <summary> 从未知数组中设置 目标数据 </summary>
        public static bool SetValueFromArray<T>(T[] array, int index, T value)
        {
            if (array == null || array.Length == 0) return false;
            if (index < 0 || index >= array.Length) return false;
            array[index] = value;
            return true;
        }

        /// <summary> 从未知数组中设置 目标数据  不在范围的 取默认值</summary>
        public static bool SetValueFromList<T>(List<T> array, int index, T value)
        {
            if (array == null || array.Count == 0) return false;
            if (index < 0 || index >= array.Count) return false;
            array[index] = value;
            return true;
        }

        /// <summary> 从未知数组中获得目标数据 </summary>
        public static T GetValueFromArray<T>(T[] array, int index, T defaultValue)
        {
            if (array == null || array.Length == 0) return defaultValue;
            if (index < 0 || index >= array.Length) return defaultValue;

            return array[index];
        }
        /// <summary> 从未知字典中获得目标数据 </summary>
        public static T GetValueFromDic<K, T>(Dictionary<K, T> arrayDic, K key, T defaultValue)
        {
            if (arrayDic == null) return defaultValue;
            if (arrayDic.ContainsKey(key) == false) return defaultValue;
            return arrayDic[key];
        }
        /// <summary> 从未知数组中获得目标数据  不在范围的 取默认值</summary>
        public static T GetValueFromList<T>(List<T> array, int index, T defaultValue)
        {
            if (array == null || array.Count == 0) return defaultValue;
            if (index < array.Count) return array[index];
            return defaultValue;
        }
        /// <summary> 数组中是否含有目标值 </summary>
        public static bool ArrayHasValue(int[] array, int value)
        {
            if (array == null || array.Length == 0) return false;
            for (int i = 0; i < array.Length; i++)
                if (array[i] == value) return true;
            return false;
        }
        public static bool ArrayHasValue(List<int> array, int value)
        {
            if (array == null || array.Count == 0) return false;
            for (int i = 0; i < array.Count; i++)
                if (array[i] == value) return true;
            return false;
        }
        /// <summary>数组扩容</summary>
        public static int[] ArrayToAddMax(int[] oldArray, int max)
        {
            if (oldArray == null) return new int[max];
            if (oldArray.Length >= max) return oldArray;

            int[] newData = new int[max];
            for (int i = 0; i < oldArray.Length; ++i)
                newData[i] = oldArray[i];

            return newData;
        }
        public static int GetRandomValueByArray(int[] array, int defValue)
        {
            if (array == null) return defValue;
            if (array.Length == 0) return defValue;
            if (array.Length == 1) return array[0];
            return Random.Range(array[0], array[1]);
        }
        /// <summary>List去重</summary>
        public static void ListRemoveRepeatValue(List<int> valueList)
        {
            int tpValue;
            for (int i = 0; i < valueList.Count - 1; i++)
            {
                tpValue = valueList[i];
                for (int j = i + 1; j < valueList.Count; j++)
                {
                    if (valueList[j] == tpValue)
                    {
                        valueList.RemoveAt(j);
                        j--;
                        continue;
                    }
                }
            }
        }

        public static void RandomShuffle<T>(List<T> list)
        {
            if (list == null || list.Count < 2) return;
            int n = list.Count;  // 获取列表的长度
            int k = 0;
            while (n > 1)
            {
                n--;
                k = RandomValue(0, n + 1, false);  // 从0到n之间随机选取索引k
                T value = list[k];        // 取出第k个元素
                list[k] = list[n];        // 将最后一个元素与第k个元素交换
                list[n] = value;
            }
        }
        /// <summary>获得%比例后的值</summary>
        public static int GetValueByRate(int value, int rate, bool subOne = false)
        {
            if (value <= 0) return value;

            if (subOne) rate -= 100;
            if (rate <= 0) return value;

            float temprate = 1.0f * rate / 100 + 1;
            return Mathf.CeilToInt(value * temprate);
        }

        /// <summary>字符串去空 分割</summary>
        public static string[] StringToStringArray(string str, char cha)
        {
            if (string.IsNullOrEmpty(str)) return null;
            str = str.Replace(" ", "");
            return str.Split(cha);
        }

        /// <summary>字符串分割 不去空格</summary>
        public static string[] StringToStringArrayWithSpeace(string str, char cha)
        {
            if (string.IsNullOrEmpty(str)) return null;
            return str.Split(cha);
        }

        /// <summary>安全的 字符串转数组</summary>
        public static int[] StringToIntArray(string str, char cha, int defValue = 0, int[] resArray = null)
        {
            var strArray = StringToStringArray(str, cha);
            if (strArray == null || strArray.Length == 0) return resArray;

            if (resArray == null || resArray.Length < strArray.Length)
                resArray = new int[strArray.Length];
            for (int i = 0; i < strArray.Length; i++)
                resArray[i] = StringToInt(strArray[i], defValue);
            return resArray;
        }
        /// <summary>安全的 字符串转数组</summary>
        public static float[] StringToFloatArray(string str, char cha, float defValue = 0, float[] resArray = null)
        {
            var strArray = StringToStringArray(str, cha);
            if (strArray == null || strArray.Length == 0) return resArray;

            if (resArray == null || resArray.Length < strArray.Length)
                resArray = new float[strArray.Length];
            for (int i = 0; i < strArray.Length; i++)
                resArray[i] = StringToFloat(strArray[i], defValue);
            return resArray;
        }
        /// <summary>安全的 字符串转List</summary>
        public static List<int> StringToIntList(string str, char cha, int defValue = 0)
        {
            List<int> resArray = new List<int>();
            var strArray = StringToStringArray(str, cha);
            if (strArray == null || strArray.Length == 0) return resArray;
            for (int i = 0; i < strArray.Length; i++)
                resArray.Add(StringToInt(strArray[i], defValue));
            return resArray;
        }

        static int _stringToIntV = 0;
        /// <summary>安全 字符转 int  </summary>
        public static int StringToInt(string str, int defValue)
        {
            if (string.IsNullOrEmpty(str)) return defValue;
            if (int.TryParse(str, out _stringToIntV))
                return _stringToIntV;
            return defValue;
        }

        static long _stringToLongV = 0;

        /// <summary>安全 字符转 long  </summary>
        public static long StringToLong(string str, long defValue)
        {
            if (string.IsNullOrEmpty(str)) return defValue;
            if (long.TryParse(str, out _stringToLongV))
                return _stringToLongV;
            return defValue;
        }

        static float _stringToFloatV = 0;
        /// <summary>安全 字符转 float </summary>
        public static float StringToFloat(string str, float defValue)
        {
            if (string.IsNullOrEmpty(str)) return defValue;
            str = str.Replace(" ", "");
            if (float.TryParse(str, out _stringToFloatV))
                return _stringToFloatV;
            return defValue;
        }
        /// <summary>去除空格 和换行 string</summary>
        public static string StringToNullEmpty(string answer)
        {
            if (string.IsNullOrEmpty(answer)) return null;
            answer = System.Text.RegularExpressions.Regex.Replace(answer, @"\s", "");
            if (string.IsNullOrEmpty(answer)) return null;
            return answer;
        }
        private static string LvStringKey = "Lv.{0}";
        public static string GetLvString(int lv)
        {
            return StringBuilderTool.Format(LvStringKey, lv.ToString());
        }
        private static string PercentStringKey = "{0}%";
        public static string GetPercentString(int num)
        {
            return StringBuilderTool.Format(PercentStringKey, num.ToString());
        }
        private static string TimesToTimesKey = "{0}/{1}";
        public static string GetTimesToTimesString(int num1, int num2)
        {
            return StringBuilderTool.Format(TimesToTimesKey, num1, num2);
        }
        private static string NumToNumKey = "{0}-{1}";
        public static string GetNumToNumKey(int num1, int num2)
        {
            return StringBuilderTool.Format(NumToNumKey, num1, num2);
        }
        private static string NumToAddKey = "{0}+";
        public static string GetNumToAddKey(int num1)
        {
            return StringBuilderTool.Format(NumToAddKey, num1);
        }
        private static string MinuteSecondKey = "{0}:{1}";
        public static string GetMinuteSecondString(int time)
        {
            if (time <= 0) return "0";
            return StringBuilderTool.Format(MinuteSecondKey, time / 60, time % 60);
        }
        private static string RedBracketKey = "({0})";
        public static string GetRedBracketKeyString(int num)
        {
            return StringBuilderTool.Format(RedBracketKey, num);
        }

        private static string XMultiplierKey = "x{0}";
        public static string GetXMultiplierString(int num)
        {
            return StringBuilderTool.Format(XMultiplierKey, num);
        }
        /// <summary>设置数组全部值 为默认值</summary>
        public static void ArrayToValue<T>(T[] arr, T value)
        {
            if (arr == null || arr.Length == 0) return;
            for (int i = 0; i < arr.Length; i++)
                arr[i] = value;
        }

        /// <summary>检测是否有中文字符</summary>
        public static bool IsHasCHZN(string inputData)
        {
            System.Text.RegularExpressions.Regex RegCHZN = new System.Text.RegularExpressions.Regex("[\u4e00-\u9fa5]");
            System.Text.RegularExpressions.Match m = RegCHZN.Match(inputData);
            return m.Success;
        }

        private static List<int> aiStageWeightList = new List<int>();//权重数组
        private static List<int> aiStageRangeList = new List<int>();//范围数组
        /// <summary>获得目标30_10;50_20  30~50 中间的值  value_rate 值_权重</summary>
        public static int GetRangeWeightValue(List<int[]> rangeWeightList)
        {
            if (rangeWeightList == null || rangeWeightList.Count == 0) return 0;
            aiStageRangeList.Clear();
            foreach (var item in rangeWeightList)
            {
                if (item.Length < 2) continue;
                aiStageRangeList.Add(item[0]);
            }
            int rangeIndex = GetWeightIndex(rangeWeightList);

            int minStage = rangeIndex <= 0 ? 0 : aiStageRangeList[rangeIndex - 1];
            int targetStage = Random.Range(minStage, aiStageRangeList[rangeIndex]);

            return targetStage;
        }
        /// <summary>获得索引值 30_10;50_20  0或者1 在权重数据 1_20;2_30;3_20;4_10 value_rate 值_权重</summary>
        public static int GetWeightIndex(List<int[]> rangeWeightList)
        {
            if (rangeWeightList == null || rangeWeightList.Count == 0) return -1;

            aiStageWeightList.Clear();
            int sumWeight = 0;
            foreach (var item in rangeWeightList)
            {
                if (item.Length < 2) continue;
                sumWeight += item[1];
                aiStageWeightList.Add(sumWeight);
            }
            if (sumWeight <= 0) return 0;
            int rangeIndex = 0;
            int randWeight = Random.Range(0, sumWeight);
            for (int i = 0; i < aiStageWeightList.Count; i++)
            {
                rangeIndex = i;
                if (randWeight <= aiStageWeightList[i]) break;
            }
            return rangeIndex;
        }

        /// <summary>随机一个值 10_5_10;25_ 0_8; 50_5_10 中间的值  等级lv_min max</summary>
        public static int GetRangeIntervalValue(List<int[]> rangeList, int lv,int defValue)
        {
            if (rangeList == null || rangeList.Count == 0) return defValue;

            int[] curInfo = null;
            for (int i = 0; i < rangeList.Count; i++)
            {
                curInfo = rangeList[i];
                if (curInfo[0] > lv) break;
            }

            if (curInfo == null) return defValue;
            return Random.Range(curInfo[1], curInfo[2]);
        }

        /// <summary>字符串转数组list 1_2;2_4;3_6;4_8;5_10</summary>
        public static List<int[]> StringToIntArrayList(string str, char splitList, char splitArray, int defValue = 0, List<int[]> defList = null)
        {
            if (string.IsNullOrEmpty(str)) return defList;
            string[] strList = str.Split(splitList);
            if (strList == null | strList.Length == 0) return defList;
            List<int[]> resList = defList == null ? new List<int[]>() : defList;
            int[] strArray = null;
            foreach (var strItem in strList)
            {
                if (string.IsNullOrEmpty(strItem)) continue;
                strArray = StringToIntArray(strItem, splitArray, defValue);
                if (strArray == null || strArray.Length == 0) continue;
                resList.Add(strArray);
            }
            return resList;
        }

        private static List<string> IntArrayStrList = new List<string>();
        /// <summary>list 1_2;2_4;3_6;4_8;5_10 转 字符串转数组</summary>
        public static string IntArrayListToString(List<int[]> listArray, char splitList, char splitArray)
        {
            if (listArray == null || listArray.Count == 0) return null;
            IntArrayStrList.Clear();
            string tpStr = null;
            foreach (var item in listArray)
            {
                tpStr = StringBuilderTool.Append(item, splitArray);
                if (string.IsNullOrEmpty(tpStr)) continue;
                IntArrayStrList.Add(tpStr);
            }
            tpStr = StringBuilderTool.Append(IntArrayStrList, splitList);
            if (string.IsNullOrEmpty(tpStr)) return null;
            return tpStr;
        }


        /// <summary>字符串转数组list 1_2;2_4;3_6;4_8;5_10</summary>
        public static Dictionary<int, int> StringToIntDic(string str, char splitList, char splitArray, int defValue = 0, Dictionary<int, int> defList = null)
        {
            if (string.IsNullOrEmpty(str)) return defList;
            string[] strList = str.Split(splitList);
            if (strList == null | strList.Length == 0) return defList;
            Dictionary<int, int> resList = defList == null ? new Dictionary<int, int>() : defList;
            int[] strArray = null;
            foreach (var strItem in strList)
            {
                if (string.IsNullOrEmpty(strItem)) continue;
                strArray = StringToIntArray(strItem, splitArray, defValue);
                if (strArray == null || strArray.Length < 2) continue;
                defList[strArray[0]] = strArray[1];
            }
            return resList;
        }

        /// <summary>从list 中获取 二维坐标数据 </summary>
        public static T GetInfoFromListByPos<T>(List<T> ListT, Vector2Int pos, Vector2Int SizeV2)
        {
            if (ListT == null) return default(T);
            if (pos.x < 0 || pos.y < 0 || pos.x >= SizeV2.x || pos.y >= SizeV2.y) return default(T);
            int index = pos.x + pos.y * SizeV2.x;
            if (index >= ListT.Count) return default(T);
            return ListT[index];
        }
        /// <summary>从数组 中获取 二维坐标数据 </summary>
        public static T GetInfoFromArrayByPos<T>(T[] ArrayT, Vector2Int pos, Vector2Int SizeV2)
        {
            if (ArrayT == null) return default(T);
            if (pos.x < 0 || pos.y < 0 || pos.x >= SizeV2.x || pos.y >= SizeV2.y) return default(T);
            int index = pos.x + pos.y * SizeV2.x;
            if (index >= ArrayT.Length) return default(T);
            return ArrayT[index];
        }
        /// <summary>获得随机数 hasMax包含最大值 </summary>
        public static int RandomValue(int min, int max, bool hasMax)
        {
            return Random.Range(min, max);
        }
        /// <summary>获得随机数 hasMax包含最大值 </summary>
        public static float RandomValue(float min, float max)
        {
            return Random.Range(min, max);
        }
        /// <summary>获得随机数 获得一个值 </summary>
        public static T RandomValue<T>(T[] array, T defValue)
        {
            if (array == null || array.Length == 0) return defValue;
            int index = RandomValue(0, array.Length, false);
            return array[index];
        }
        /// <summary>获得随机数 获得一个值 </summary>
        public static T RandomValue<T>(List<T> list, T defValue)
        {
            if (list == null || list.Count == 0) return defValue;
            int index = RandomValue(0, list.Count, false);
            return list[index];
        }
        private static List<int> RandomValueIndexList = new List<int>();
        /// <summary>获得随机数 获得N值 List<int> 下标</summary>
        public static List<int> RandomValueList<T>(List<T> list, int num)
        {
            RandomValueIndexList.Clear();
            if (list == null || list.Count == 0) return RandomValueIndexList;
            if (num > list.Count) num = list.Count; //越界问题
            int index = 0;
            while (num > 0)
            {
                index = RandomValue(0, list.Count, false);
                if (RandomValueIndexList.Contains(index)) continue;
                RandomValueIndexList.Add(index);
                num--;
            }
            return RandomValueIndexList;
        }
    /// <summary>获得随机数 概率  </summary>
    public static bool RandomValueContain(int min, int max, bool hasMax, int containValue)
        {
            return RandomValue(min, max, hasMax) <= containValue;
        }
        /// <summary>是否是标准容器</summary>
        public static bool IsStandardCollection<T>(List<T> ListT, int maxIndex)
        {
            if (ListT == null) return false;
            if (ListT.Count < maxIndex) return false;
            return true;
        }
        /// <summary>是否是标准容器</summary>
        public static bool IsStandardCollection<T>(T[] ArrayT, int maxIndex)
        {
            if (ArrayT == null) return false;
            if (ArrayT.Length < maxIndex) return false;
            return true;
        }
        /// <summary>是否是标准容器</summary>
        public static bool IsStandardCollection<K, T>(Dictionary<K, T> DicKT, int maxIndex)
        {
            if (DicKT == null) return false;
            if (DicKT.Count < maxIndex) return false;
            return true;
        }

        /// <summary>N天换算成秒</summary>
        public static int GetDayToSecond(int day)
        {
            return 86400 * day;
        }

        private static int[] MinAndMaxAreaValue = new int[2];
        /// <summary> 获得 数值区间 数 </summary>
        public static int[] GetMinAndMaxAreaValue(int min, int max, int index, int num)
        {
            if ((max - min) < num)
            {
                MinAndMaxAreaValue[0] = min;
                MinAndMaxAreaValue[1] = max;
                return MinAndMaxAreaValue;
            }
            int Oddnum = num % 2;//奇 偶 数
            int sunNum = (num - Oddnum) / 2;

            int addMaxNum = 0;
            int minIndex = index - sunNum;
            if (minIndex < 0)
            {
                addMaxNum = System.Math.Abs(minIndex);
                minIndex = 0;
            }
            int maxIndex = index + sunNum + addMaxNum;
            if (maxIndex > max)
            {
                sunNum = maxIndex - max;
                minIndex -= sunNum;
                if (minIndex < min) minIndex = min;
                maxIndex = max;
            }

            if (minIndex > min) minIndex -= Oddnum;
            else if (maxIndex < max) maxIndex += Oddnum;

            MinAndMaxAreaValue[0] = minIndex;
            MinAndMaxAreaValue[1] = maxIndex;
            return MinAndMaxAreaValue;
        }

        #endregion

        #region 设置Material的属性 用MaterialPropertyBlock

        private static List<string[]> ColorSList = new List<string[]>()
        {
            new string[] { "_Color", "_ColorS" },
            new string[] { "_MainColor" },
            new string[] { "_frenelcolor", "_Color" },
        };
        public static string[] GetMaterialColor(int colorIndex)
        {
            return GetValueFromList(ColorSList, colorIndex, null);
        }

        static MaterialPropertyBlock Materialprop = new MaterialPropertyBlock();
        /// <summary>设置RenderMater的颜色 </summary>
        public static void SetRenderMaterialColor(Renderer renderer, string colorName, Color color)
        {
            if (renderer == null) return;
            if (string.IsNullOrEmpty(colorName)) return;

            renderer.GetPropertyBlock(Materialprop);
            Materialprop.SetColor(colorName, color);
            renderer.SetPropertyBlock(Materialprop);
        }
        /// <summary>设置RenderMater的颜色 </summary>
        public static void SetRenderMaterialColor(Renderer renderer, string[] colorNameS, Color[] colorS)
        {
            if (renderer == null) return;
            if (colorNameS == null || colorS == null) return;
            if (colorNameS.Length == 0 || colorS.Length == 0) return;
            renderer.GetPropertyBlock(Materialprop);
            for (int i = 0; i < colorNameS.Length; i++)
            {
                if (string.IsNullOrEmpty(colorNameS[i])) continue;
                Materialprop.SetColor(colorNameS[i], colorS[i]);
            }
            renderer.SetPropertyBlock(Materialprop);
        }
        /// <summary>设置RenderMater的 float 值</summary>
        public static void SetRenderMaterialFloat(Renderer renderer, string valueName, float value)
        {
            if (renderer == null) return;
            if (string.IsNullOrEmpty(valueName)) return;

            renderer.GetPropertyBlock(Materialprop);
            Materialprop.SetFloat(valueName, value);
            renderer.SetPropertyBlock(Materialprop);
        }
        /// <summary>设置RenderMater的图片偏移</summary>
        public static void SetRenderMaterialTextureScale(Renderer renderer, string valueName, Vector4 value)
        {
            if (renderer == null) return;
            if (string.IsNullOrEmpty(valueName)) return;

            renderer.GetPropertyBlock(Materialprop);
            Materialprop.SetVector(valueName, value);
            renderer.SetPropertyBlock(Materialprop);
        }

        /// <summary>设置粒子的startColor</summary>
        public static void SetParticleSystemStartColor(ParticleSystem renderer, Color color)
        {
            if (renderer == null) return;
            var main = renderer.main;
            main.startColor = new ParticleSystem.MinMaxGradient(color);
        }

        /// <summary>查找父节点最近的Canvas</summary>
        public static Canvas FindNearCanvas(Transform transform)
        {
            Canvas canvas = null;
            if (transform.parent != null)
            {
                canvas = transform.parent.GetComponent<Canvas>();
                if (canvas == null)
                {
                    canvas = FindNearCanvas(transform.parent);
                }
                return canvas;
            }
            return canvas;
        }

        #endregion


        #region sortHelp
        private static Queue<SortHelpItem> TpSortHelpItemPool = new Queue<SortHelpItem>();
        private static List<SortHelpItem> HelpItemList = new List<SortHelpItem>();
        private static List<SortHelpItem> TpHelpItemList = new List<SortHelpItem>();


        private static void SortHelpItemList(List<SortHelpItem> itemlist)
        {
            if (IsStandardCollection(itemlist, 2) == false) return;
            TpHelpItemList.Clear();
            SortHelpItem helpItem = null;
            bool hasInsert = false;
            for (int i = 0; i < itemlist.Count; i++)
            {
                helpItem = itemlist[i];
                hasInsert = false;
                for (int k = 0; k < TpHelpItemList.Count; k++)
                {
                    if (helpItem.Compare(TpHelpItemList[k]))
                    {
                        TpHelpItemList.Insert(k, helpItem);
                        hasInsert = true;
                        break;
                    }
                }
                if (hasInsert == false)
                    TpHelpItemList.Add(helpItem);
            }
            itemlist.Clear();
            itemlist.AddRange(TpHelpItemList);
            TpHelpItemList.Clear();
        }

        /// <summary>获取对象 从引用对象池(不会自动创建)</summary>
        private static SortHelpItem SpwanSortHelpItem(float dis, object target)
        {
            SortHelpItem resItem = TpSortHelpItemPool.Count == 0 ? new SortHelpItem() : TpSortHelpItemPool.Dequeue();
            resItem.InitItem(dis, target);
            return resItem;
        }
        private static void DeSpwanSortHelpItem(List<SortHelpItem> sortHelplist)
        {
            if (IsStandardCollection(sortHelplist, 0) == false) return;

            for (int i = 0; i < sortHelplist.Count; i++)
            {
                sortHelplist[i].Clear();
                TpSortHelpItemPool.Enqueue(sortHelplist[i]);
            }

            sortHelplist.Clear();
        }
        private class SortHelpItem
        {
            private float disValue;
            private object targetItem;
            public void InitItem(float dis, object target)
            {
                disValue = dis;
                targetItem = target;
            }
            public object GetTargetItem()
            {
                return targetItem;
            }
            public bool Compare(SortHelpItem otherItem)
            {
                return disValue > otherItem.disValue;
            }
            public void Clear()
            {
                disValue = 0;
                targetItem = null;
            }
        }


        #endregion



        #region int 位运算 31位
        public const int IntMaxBit = 2147483647;// 11111.... x31  31位 都为1
        public const int IntMinBit = 1073741824;// 1000...x31  30位为1  其他为都为0

        /// <summary>位值 是不是1</summary>
        public static bool isBit1(int bitValue, int index)
        {
            return (bitValue >> index & 1) == 1;
        }
        /// <summary>设置 位值 为1</summary>
        public static int SetBit1(int bitValue, int index)
        {
            return bitValue | 1 << index;
        }
        /// <summary>设置 位值 为0</summary>
        public static int SetBit0(int bitValue, int index)
        {
            return bitValue & ~(1 << index);
        }
        /// <summary>设置 位值 为0</summary>
        public static int SetBitBool(int bitValue, int index, bool istrue)
        {
            return istrue ? SetBit1(bitValue, index) : SetBit0(bitValue, index);
        }
        #endregion
    }
}
